﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;
using System.Configuration;
using System.Security.Cryptography;

namespace DusonFramework.Core.Security
{
    public class SymmetricAlgorithmProvider<T> : ICryptographyProvider where T: SymmetricAlgorithm, new()
    {
        #region Private Fields

        private T _provider = new T();

        private string bKeys = string.Empty;
        private string bIVs = string.Empty;

        #endregion

        #region Constructor

        public SymmetricAlgorithmProvider() { }

        public SymmetricAlgorithmProvider(string keys, string ivs)
        {
            bKeys = keys;
            bIVs = ivs;
        }

        #endregion

        #region Public Properties

        public string Keys
        {
            get { return bKeys; }
            set { bKeys = value; }
        }
        public string IVs 
        {
            get { return bIVs; }
            set { bIVs = value; }
        }

        #endregion

        #region Public Methods

        public string Encrypting(string source)
        {
            return Encrypting(source, Keys, IVs);
        }

        public string Decrypting(string source)
        {
            return Decrypting(source, Keys, IVs);
        }

        public string Encrypting(string source, string keys, string ivs)
        {
            byte[] bKeys = Encoding.ASCII.GetBytes(keys);
            byte[] bIVs = Encoding.ASCII.GetBytes(ivs);

            byte[] bEncrypted = CryptoTransform(_provider.CreateEncryptor(bKeys, bIVs),
                Encoding.UTF8.GetBytes(source));

            return Convert.ToBase64String(bEncrypted);
        }

        public string Decrypting(string source, string keys, string ivs)
        {
            byte[] bKeys = Encoding.ASCII.GetBytes(keys);
            byte[] bIVs = Encoding.ASCII.GetBytes(ivs);

            byte[] bDecrypted = CryptoTransform(_provider.CreateDecryptor(bKeys, bIVs),
                Convert.FromBase64String(source));

            return Encoding.UTF8.GetString(bDecrypted);
        }

        #endregion

        #region Private Methods

        private byte[] CryptoTransform(ICryptoTransform cryptoTransform, byte[] bSrcs)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write))
                {
                    cs.Write(bSrcs, 0, bSrcs.Length);
                    cs.FlushFinalBlock();

                    ms.Position = 0;

                    return ms.ToArray();
                }
            }
        }

        #endregion
    }
}
